<template>
  <div style="border: 1px solid #ccc">
    <Toolbar style="border-bottom: 1px solid #ccc" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
    <Editor style="height: 500px; overflow-y: hidden;" v-model="valueHtml" :defaultConfig="editorConfig" :mode="mode"
      @onCreated="handleCreated" @onBlur="handleBlur" @onChange="handleChange"/>
  </div>
</template>
<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { onBeforeUnmount, ref, shallowRef, defineComponent, onMounted, defineEmits, toRefs, defineProps } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IEditorConfig } from '@wangeditor/editor'
// 导入消息提示框
import { ElMessage } from 'element-plus';
// 导入记录地址信息
import { URL } from '../http/env.config';
// 定义组件
defineComponent({ components: { Editor, Toolbar } })
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
// 内容HTML
let valueHtml: string | any = ref('')
// 获取富文本框的内容 （valueHtml.value）
// 记录父组件传递的数据
const props = defineProps({
  //子组件接收父组件传递过来的值
  contentxxx: [String,Object],
})
// 组件挂载完成执行
onMounted(() => {
  setTimeout(() => {
    //使用父组件传递过来的值
    const { contentxxx } = toRefs(props)
    // console.log('2.0',contentxxx);
    // 判断父组件是否传递数据
    if(contentxxx){
      valueHtml.value = contentxxx.value;
    }
  }, 300)
})
// 工具栏配置
const toolbarConfig = {}
const editorConfig: Partial<IEditorConfig> | any = { placeholder: '请输入内容...', MENU_CONF: {} }
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
// 创建实例
const handleCreated = (editor: any) => {
  editorRef.value = editor // 记录 editor 实例，重要！
}
// 默认模板
const mode = ref('default')
// 自定义粘贴
const customPaste = (editor: any, event: any, callback: any) => {
  // console.log('ClipboardEvent 粘贴事件对象', event)
  const html = event.clipboardData.getData('text/html') // 获取粘贴的 html
  // const text = event.clipboardData.getData('text/plain') // 获取粘贴的纯文本
  // const rtf = event.clipboardData.getData('text/rtf') // 获取 rtf 数据（如从 word wsp 复制粘贴）
  // 自定义插入内容
  editor.insertText(html)
  // 返回 false ，阻止默认粘贴行为
  event.preventDefault()
  // 返回值（注意，vue 事件的返回值，不能用 return）
  callback(false)
  // 返回 true ，继续默认的粘贴行为
  // callback(true)
}
// 想办法把子组件的值传给父组件
// 使用defineEmits创建名称，接受一个数组
const emit = defineEmits(['handleBlurxxxx'])
// 监听失去焦点
const handleBlur = (editor: any) => {
  // console.log('blur', editor)
  // console.log(valueHtml.value)
  let param = {
    content: valueHtml.value
  }
  //传递给父组件
  emit('handleBlurxxxx', param)
}


const handleChange = (editor: any) => {
  // console.log('blur', editor)
  // console.log(valueHtml.value)
  let param = {
    content: valueHtml.value
  }
  //传递给父组件
  emit('handleBlurxxxx', param)
}



// 监听值变化
// const handleChange = (editor: any) => {
//   // console.log('change:', editor.children) 
//   console.log(valueHtml.value)
// }
// 上传图片
editorConfig.MENU_CONF['uploadImage'] = {
  // 服务器上传图片接口：http://127.0.0.1:5000/upload/article/upload
  server: `${URL}/article/upload`,
  // 图片key
  fieldName: 'photo',
  // 单个文件的最大体积限制，默认为 2M
  maxFileSize: 1 * 1024 * 1024, // 1M
  // 最多可上传几个文件，默认为 100
  maxNumberOfFiles: 1,
  // 小于该值就插入 base64 格式（而不上传），默认为 0
  base64LimitSize: 5 * 1024, // 5kb
  // 上传之前触发
  onBeforeUpload(file: any) {
    // file 选中的文件，格式如 { key: file }
    return file
  },
  // 上传进度的回调函数
  onProgress(progress: any) {
    // progress 是 0-100 的数字
    // console.log('progress', progress)
  },
  // 单个文件上传成功之后
  onSuccess(file: any, res: any) {
    // res记录这图片信息
    // 可以把图片信息记录在数组中，方便以后删除冗余代码
    // console.log(`${file.name} 上传成功`, res)
    // ElMessage(`${file.name} 上传成功`);
  },
  // 单个文件上传失败
  onFailed(file: any, res: any) {
    // console.log(`${file.name} 上传失败`, res)
    ElMessage(`${file.name} 上传失败`);
  },
  // 上传错误，或者触发 timeout 超时
  onError(file: any, err: any, res: any) {
    // console.log(`${file.name} 上传出错`, err, res)
    ElMessage(`${file.name} 上传出错`);
  },
}
// 自定义校验图片
function customCheckImageFn(src: string, alt: string, url: string): boolean | undefined | string {
  if (!src) {
    return
  }
  if (src.indexOf('http') !== 0) {
    return '图片网址必须以 http/https 开头'
  }
  return true
  // 返回值有三种选择：
  // 1. 返回 true ，说明检查通过，编辑器将正常插入图片
  // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
  // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
}
// 转换图片链接
function customParseImageSrc(src: string): string {
  if (src.indexOf('http') !== 0) {
    return `http://${src}`
  }
  return src
}
// 编辑图片
// deleteImage
editorConfig.MENU_CONF['editImage'] = {
  onUpdatedImage(imageNode: any) {
    if (imageNode == null) return
    const { src, alt, url } = imageNode
    console.log('updated image', src, alt, url);
  },
  checkImage: customCheckImageFn,
  parseImageSrc: customParseImageSrc,
}
// 代码高亮
editorConfig.MENU_CONF['codeSelectLang'] = {
  // 代码语言
  codeLangs: [
    { text: 'CSS', value: 'css' },
    { text: 'HTML', value: 'html' },
    { text: 'XML', value: 'xml' },
    // 其他
  ]
}
// 设置字号
editorConfig.MENU_CONF['fontSize'] = {
  fontSizeList: [
    // 元素支持两种形式
    //   1. 字符串；
    //   2. { name: 'xxx', value: 'xxx' }
    '12px',
    '16px',
    { name: '24px', value: '24px' },
    '40px',
  ]
}
// 配置表情
editorConfig.MENU_CONF['emotion'] = {
  emotions: '😀 😃 😄 😁 😆 😅 😂 🤣 😊 😇 🙂 🙃 😉'.split(' ') // 数组
}





</script>